package com.bohan.hit;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Vector;
import java.util.Map.Entry;

import org.json.JSONArray;
import org.json.JSONException;

import com.bohan.main.Main;
import com.bohan.main.WriterJason;

import Jama.Matrix;


public class Hit {
	
	Vector <Integer> [] matrixNeighIn;
	Vector <Integer> [] matrixNeighOut;
	HashMap <String, Integer> linkMat;
	HashMap <String, Double> simMat;
	//HashMap <String, Integer> simMatOut;
	public Hit(int size){
		//linkMatrix = new float[size][size];
		linkMat = new HashMap<String, Integer>();
		simMat = new HashMap<String, Double>();
		//simMatOut = new HashMap<String, Integer>();
	}
	public void setNeigh(int size)
	{
		matrixNeighIn = new Vector[size];
		matrixNeighOut = new Vector[size];
		for(int i = 0; i < size ; i ++){
			matrixNeighIn[i] = new Vector<Integer>();
			matrixNeighOut[i] = new Vector<Integer>();
		}
		Main.randommax = size;
	}
	public Vector <Integer>[] getNeighIn()
	{
		return matrixNeighIn;
	}
	public Vector <Integer>[] getNeighOut()
	{
		return matrixNeighOut;
	}
	public String show(int result, String fileIn, String fileRand) throws IOException, NumberFormatException, JSONException
	{
		List< Map.Entry<String, Double> > list = new ArrayList< Map.Entry<String, Double> >(simMat.entrySet());
        Collections.sort(list,new Comparator< Map.Entry<String, Double> >() {
            
			public int compare(Entry<String, Double> o1,
					Entry<String, Double> o2) {
				return o1.getValue().compareTo(o2.getValue());
			}

        });
        
        WriterJason wj = new WriterJason();
        return wj.write2Jason(fileIn, fileRand, list, linkMat, result);
        /*
        for(Map.Entry<String, Double> mapping : list){
        		String []key = mapping.getKey().split(",");
        		if(linkMat.get(mapping.getKey()) != null)
        		{
        			continue;
        		}
        		if(result -- > 0)
        			//System.out.println(key[0] + "," + key[1] +":"+mapping.getValue());
        			System.out.println(key[0] + "," + key[1] );
        		else
        			break;
        }
        */
	}
	public void readFile(String filename) throws NumberFormatException, IOException
	{
		File f = new File(filename);
		InputStream in = new FileInputStream(f);
		InputStreamReader ir = new InputStreamReader(in);
		BufferedReader br = new BufferedReader(ir);
		int ch = -1, first2Count = 0, firstNum = 0, secondNum = 0;
		String num = "";
		String firstStr = "", secondStr = "";
		while( (ch = br.read()) != -1 )
		{
			num += (char)ch;
			if(ch == '\t')
			{
				first2Count ++;
				if(first2Count == 1)
				{
					firstStr = num.trim();
					firstNum = Integer.parseInt(firstStr);
					//firstNum = Integer.parseInt(num.trim());
				}
				if(first2Count == 2)
				{
					secondStr = num.trim();
					secondNum = Integer.parseInt(secondStr);
					if(firstNum < Main.datarange && secondNum < Main.datarange){
						if(linkMat.get(firstStr + "," + secondStr) == null )
						{
							linkMat.put(firstStr + "," + secondStr, 1);
							matrixNeighOut[firstNum].add(secondNum);
							matrixNeighIn[secondNum].add(firstNum);
						}
					}
				}
				num = "";
			}
			if(ch == '\n'){
				first2Count = 0;
				num = "";
			}
		}
		br.close();
		ir.close();
		in.close();
	}
	public void clear(Vector <Integer> [] neigh)
	{
		linkMat = null;
		neigh = null;
	}
	public void compute(Vector <Integer> [] neigh, int size)
	{
		Random random = new Random();
		//System.out.println(Main.randommax);
		Map <Integer, Integer> m = new HashMap<Integer, Integer>();
		for (int i = 0; i < size; i++) { 
			m.clear();
	        int vertex = i;
	        
	        int currentVertex = vertex; 
	       
	        for(int step = 1; true; step++ ) { 
	            int rand = random.nextInt(Main.randommax + 1);
	        	//if( neigh[currentVertex].size() < 1 || (double)rand / Main.randommax < Main.alpha ) { 
	            if( neigh[currentVertex].size() == 0 ) {
	                currentVertex = vertex; 
	            } else {                     
	                int randomNeighbor = rand % neigh[currentVertex].size(); 
	                currentVertex = neigh[currentVertex].get(randomNeighbor); 
	            } 
	            if( m.get(currentVertex) == null)
	            	m.put(currentVertex, step * neigh[currentVertex].size());
	             
	            if( step == Main.step ) { 
	            	break;
	            } 
	           
	        }
	        
	        List< Map.Entry<Integer,Integer> > list = new ArrayList< Map.Entry<Integer,Integer> >(m.entrySet());
	        Collections.sort(list,new Comparator< Map.Entry<Integer,Integer> >() {
	            
				public int compare(Entry<Integer, Integer> o1,
						Entry<Integer, Integer> o2) {
					return o1.getValue().compareTo(o2.getValue());
				}

	        });
	        int key ;
	        double value = 0.0 ;
	        for(Map.Entry<Integer, Integer> mapping : list){
	        	if( (value = mapping.getValue()) != 0 && (key = mapping.getKey()) != i ){
	        		
	        		if(simMat.get(i + "," + mapping.getKey()) == null)
	        			simMat.put(i + "," + mapping.getKey(), value);
	        		else{
	        			double vtemp = simMat.get(i + "," + mapping.getKey()) + value;
	        			simMat.put(i + "," + mapping.getKey(), vtemp);
	        		}
	        	}
	        }
		}
	}
	
}
